package com.huiquan.analysis.dao;

import com.huiquan.analysis.domain.*;
import com.huiquan.framework.base.EnhancedBaseDao;
import com.huiquan.framework.utils.DateUtils;
import com.ibatis.sqlmap.client.SqlMapClient;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class AnalysisSentenceDao extends EnhancedBaseDao<AnalysisSentence> {

    @Resource(name = "sqlMapClient")
    private SqlMapClient sqlMapClient;

    public static final String space = "ANALYSIS_SENTENCE.";

    public AnalysisSentenceDao() {
        super(space);
    }

    @SuppressWarnings("unchecked")
    public List<Map<String, Object>> retrieveSidAndSentence(int type, int labelStatus) {
        Map<String, Object> param = new HashMap<>();
        param.put("type", type);
        param.put("labelStatus", labelStatus);
        return (List<Map<String, Object>>) this.list(space + "RETRIEVE_SID_AND_SENTENCE", param, sqlMapClient);
    }

    @SuppressWarnings("unchecked")
    public List<Map<String, Object>> retrieveXbsSidAndSentence(int bmeFlag, int labelStatus, String secondType) {
        Map<String, Object> param = new HashMap<>();
        param.put("bmeFlag", bmeFlag);
        param.put("labelStatus", labelStatus);
        param.put("secondType", secondType);
        return (List<Map<String, Object>>) this.list(space + "RETRIEVE_XBS_SID_AND_SENTENCE", param, sqlMapClient);
    }

    /**
     * 根据Map中的检索条件获取AnalysisSentence列表
     *
     * @param param
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<AnalysisSentence> retrieveListNoLimit(Map<String, Object> param) {
        return (List<AnalysisSentence>) this.list(space + "RETRIEVE_LIST_NOLIMIT", param, sqlMapClient);
    }


    /**
     * 根据sentence的id搜索出类似ES索引所需要的数据
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<AnalysisSentenceVocabularyES> retrieveZsVocabularyListBySid(long sid) {
        Map<String, Object> param = new HashMap<>();
        param.put("sid", sid);
        return (List<AnalysisSentenceVocabularyES>) this.list(space + "RETRIEVE_ZS_VOCABULARY_LIST_BY_SID", param, sqlMapClient);
    }

    /**
     * 空检索条件下获取主诉的数据列表
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<AnalysisSentence> retrieveZsListNullSearch() {
        return (List<AnalysisSentence>) this.list(space + "RETRIEVE_ZS_LIST_NULL_SEARCH", sqlMapClient);
    }

    /**
     * 空检索条件下获取未标记现病史的数据列表
     *
     * @param secondType
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<AnalysisSentence> retrieveXbsListNullSearchUnlabeled(String secondType) {
        Map<String, Object> param = new HashMap<>();
        param.put("secondType", secondType);
        return (List<AnalysisSentence>) this.list(space + "RETRIEVE_XBS_LIST_NULL_SEARCH_UNLABELED", param, sqlMapClient);
    }

    /**
     * 空检索条件下获取无法标记现病史的数据列表
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<AnalysisSentence> retrieveXbsCanNotTag(Map<String, Object> param) {
        return (List<AnalysisSentence>) this.list(space + "RETRIEVE_XBS_CANNOT_TAG", param, sqlMapClient);
    }

    /**
     * 空检索条件下获取已标记现病史的数据列表
     *
     * @param secondType
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<AnalysisSentence> retrieveXbsListNullSearchLabeled(String secondType) {
        return (List<AnalysisSentence>) this.list(space + "RETRIEVE_XBS_LIST_NULL_SEARCH_LABELED", secondType, sqlMapClient);
    }

    @Override
    public int update(AnalysisSentence entity) {
        entity.setGmtModified(DateUtils.convertCurrentTimeFormat());
        return super.update(space + "UPDATE", entity, sqlMapClient);
    }

    /**
     * 根据sentence的id字符串得到sid和属性映射的集合
     *
     * @param idStr
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<HashMap<String, Object>> selectVocabularySidPropertyMapper(String idStr) {
        return (List<HashMap<String, Object>>) this.list(space + "SELECT_VOCABULARY_SID_PROPERTY_MAPPER_BY_IDSTR",
                idStr, sqlMapClient);
    }

    /**
     * 插入一条未标记语句
     *
     * @param param
     */
    public void insertUnlabeledSentenceXbs(Map<String, Object> param) {
        this.insert(space + "INSERT_SENTENCE_XBS_UNLABELED", param, sqlMapClient);
    }

    /**
     * 初始化现病史BME标注数据
     *
     * @param dataNumber
     */
    public void initXbsBmeData(Integer dataNumber) {
        this.insert(space + "INIT_XBS_BME_DATA", dataNumber, sqlMapClient);
    }

    /**
     * 根据sid得到语句上下文
     *
     * @param sid
     * @return
     */
    @SuppressWarnings("unchecked")
    public Map<String, String> selectContextBySid(long sid) {
        return (Map<String, String>) this.object(space + "SELECT_CONTEXT_BY_SID", sid, sqlMapClient);
    }

    /**
     * 得到外包人员的数量
     *
     * @return
     */
    public int selectOutsourcingPersonnelCount() {
        return (int) this.object(space + "SELECT_OUTSOURCING_PERSONNEL_COUNT", sqlMapClient);
    }

    /**
     * 清除未标注的现病史数据
     */
    public void deleteUnlabelXbsBmeData() {
        this.delete(space + "DELETE_UNLABEL_XBS_BME_DATA", sqlMapClient);
    }

    /**
     * 根据词语长度来初始化现病史数据
     *
     * @param lowLength
     * @param highLength
     * @param dataNumber
     */
    public void initXbsBmeDataBySentenceLength(String secondType, Integer lowLength, Integer highLength, Integer dataNumber) {
        Map<String, Object> params = new HashMap<>();
        params.put("secondType", secondType);
        params.put("lowLength", lowLength);
        params.put("highLength", highLength);
        // TODO: 暂时取消数量限制
        //params.put("dataNumber", dataNumber);
        this.insert(space + "INIT_XBS_BME_DATA_BY_SENTENCE_LENGTH", params, sqlMapClient);
    }

    /**
     * 得到词语长度设置
     *
     * @param type
     * @param grade
     * @return
     */
    public Integer getSentenceLength(int type, int grade) {
        Map<String, Object> params = new HashMap<>();
        params.put("type", type);
        params.put("grade", grade);
        return (Integer) this.object(space + "SELECT_SENTENCE_LENGTH", params, sqlMapClient);
    }


    /**
     * 删除analysis进入已删除表
     *
     * @param id
     */
    public void insertDel(long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        this.update(space + "INSERT_DEL_ANALYSIS", params, sqlMapClient);
    }

    /**
     * 删除analysis进入已删除表标注为无法标注
     *
     * @param id
     */
    public void insertCannotTag(long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        this.update(space + "INSERT_CANNOTTAG_ANALYSIS", params, sqlMapClient);
    }

    /**
     * 从已删除表中删除sentence，移入analysis表，变为未标注sentence，并返回自增ID
     *
     * @param id
     */
    public long recoverCanTag(long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        return (long) this.insert(space + "INSERT_CANTAG_ANALYSIS", params, sqlMapClient);
    }

    /**
     * 使用自增ID恢复analysis
     *
     * @param id
     */
    public void recoverCanTagVocab(long id, long newId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        params.put("newId", newId);
        this.update(space + "RECOVER_ANALYSIS_VOCAB", params, sqlMapClient);
    }

    /**
     * 查询已删除的记录
     *
     * @param param
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<AnalysisSentence> retrieveDelList(Map<String, Object> param) {
        return (List<AnalysisSentence>) this.list(space + "RETRIEVE_DEL_LIST", param, sqlMapClient);
    }


    /**
     * 获取已删除的数量
     *
     * @return
     */
    public int retrieveDelSize(Map<String, Object> param) {
        Integer size = (Integer) this.object(space + "RETRIEVE_DEL_SIZE", param, sqlMapClient);
        return size == null ? 0 : size;
    }

    /**
     * 恢复analysis数据
     *
     * @param id
     */
    public Long recoverAnalysis(long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        return (Long) this.insert(space + "RECOVER_ANALYSIS", params, sqlMapClient);
    }

    /**
     * 恢复analysis数据
     *
     * @param id
     */
    public void recoverAnalysisVocab(long id, long newId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        params.put("newId", newId);
        this.update(space + "RECOVER_ANALYSIS_VOCAB", params, sqlMapClient);
    }

    /**
     * 根据id获取已删除表中的对象
     *
     * @param id
     * @return
     */
    @SuppressWarnings("unchecked")
    public AnalysisSentence retrieveDelObjectById(Long id) {
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        return (AnalysisSentence) this.object(space + "RETRIEVE_DEL_OBJECT_BY_ID", param, sqlMapClient);
    }

    /**
     * 根据id获取未删除表中的的对象
     *
     * @param id
     * @return
     */
    @SuppressWarnings("unchecked")
    public AnalysisSentence retrieveObjectById(Long id) {
        Map<String, Object> param = new HashMap<>();
        param.put("id", id);
        return (AnalysisSentence) this.object(space + "RETRIEVE_OBJECT_BY_ID", param, sqlMapClient);
    }

    /**
     * 根据id获取对象
     *
     * @param id
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<AnalysisSentenceSubdivision> retrieveSubObjectById(Long id, boolean sidFlag) {
        Map<String, Object> param = new HashMap<>();
        if (sidFlag) {
            param.put("sid", id);
        } else {
            param.put("ssid", id);
        }
        return (List<AnalysisSentenceSubdivision>) this.list(space + "RETRIEVE_SUB_LIST_BY_ID", param, sqlMapClient);
    }

    public Long insertSubdivisionSentence(AnalysisSentence sentence, Long sid, boolean isSidFlag, String type, String secondType, User user) {
        Map<String, Object> params = new HashMap<>();
        if (isSidFlag) {
            params.put("sid", sid);
        } else {
            params.put("ssid", sid);
        }

        params.put("sentence", sentence.getSentence());
        params.put("type", type);
        if (StringUtils.isNotBlank(secondType)) {
            params.put("secondType", secondType);
        }
        params.put("uid", user.getUserId());
        return (Long) this.insert(space + "INSERT_SUBDIVISION_SENTENCE", params, sqlMapClient);

    }

    public void deleteSubdivisionBySidList(List<Long> deleteSid) {
        Map<String, Object> params = new HashMap<>();
        StringBuilder sidStr = new StringBuilder();
        for (Long sid : deleteSid) {
            sidStr.append(sid).append(",");
        }
        params.put("sids", sidStr.toString().substring(0, sidStr.length() - 1));
        this.delete(space + "DELETE_SUBDIVISION_SENTENCE_BY_ID", params, sqlMapClient);
    }

    public AnalysisSentenceSubdivision retrieveSubdivisionObjectById(Long id) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        return (AnalysisSentenceSubdivision) this.object(space + "RETRIEVE_SUB_BY_ID", params, sqlMapClient);

    }

    public void deleteByIds(String childIds) {
        this.delete(space + "DELETE_BY_IDS", childIds, sqlMapClient);
    }

    public void insertEnlargeXbs(Map<String, Object> sentence) {
        this.insert(space + "INSERT_ENLARGE_XBS", sentence, sqlMapClient);
    }

    public void initRepetitionRate() {
        this.update(space + "INIT_REPETITION_RATE", sqlMapClient);
    }

    public List<Map<String, Object>> retrieveLabeledSentence() {
        return (List<Map<String, Object>>) this.list(space + "RETRIEVE_LABELED_SENTENCE", sqlMapClient);
    }

    public void updateSubValidFlag(long id, String check, Long uid) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        params.put("check", check);
        params.put("uid", uid);
        this.update(space + "UPDATE_SUB_VALID_FLAG", params, sqlMapClient);
    }
}
